`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////Asyncsys Lab////////////////////////////////////////
// Author: Zhenbang Kang
// Email: kangzhb20@lzu.edu.cn
// Create Date: 2022/06/10 
// Module Name: chip_top
// Project Name: ac8051 (Asynchronous Click 8051)
// Target Devices: XC7A100TFGG484-2
// Tool Versions: Vivado 2019.1
// Description:Chip Top Module 
// Revision: V2.0
//////////////////////////////////////////////////////////////////////////////////
`include "D:/fpga_8051/code/fpga/rtl/include/DW8051_package.v"
`include "D:/fpga_8051/code/fpga/rtl/include/DW8051_parameter.v"

module chip_top(                rst_n ,
                                sys_clk_p,
                                sys_clk_n,
                                uart_rx,
                                uart_tx
		                );
  input                      rst_n;
  input                      sys_clk_p;
  input                      sys_clk_n;
  input                      uart_rx;           //fpga receive data
  output                     uart_tx;            //fpga send data
  /***************************signal**********************************/
 wire                       rst_n;
 wire                       i_rst_n;
// wire                       o_rst_n;
 wire                       clk_in1_p;
 wire                       clk_in1_n;
 wire                       sys_clk;

 wire                       uart_rx;
 wire                       uart_tx;
(* dont_touch = "true" *) reg                        in_R;
//wire                        in_R;
  //interrupt
  wire                       int0_n      ;
  wire                       int1_n      ;
  
  //serial port 0
 wire                       rxd0_in     ;
 wire                       rxd0_out    ;
 wire                       txd0        ;
  
  //timer0/1
  wire                       t0          ;
  wire                       t1          ;
  wire                       t0_out      ;
  wire                       t1_out      ;
//  reg[3:0]              led_r;             //define the first stage register , generate two D Flip-flop 
//  reg[3:0]              led_r1;            //define the second stage register ,generate two D Flip-flop
  //interal ram , no read enable signal
(* dont_touch = "true" *)  wire [ 7:0]                ram_addr    ;
(* dont_touch = "true" *)  wire [ 7:0]                ram_data_out;
(* dont_touch = "true" *)  wire [ 7:0]                ram_data_in ;
(* dont_touch = "true" *)  wire                       ram_wen     ;
  
  //interal rom
 (* dont_touch = "true" *) wire [ 12:0]               rom_addr    ;
 (* dont_touch = "true" *) wire [ 7:0]                rom_data    ;
 (* dont_touch = "true" *) wire                       rom_rd      ;
  
  //sfr signal
 (* dont_touch = "true" *)  wire [ 7:0]                sfr_addr;    
 (* dont_touch = "true" *)  wire [ 7:0]                sfr_data_out;
 (* dont_touch = "true" *)  wire [ 7:0]                sfr_data_in ;
 (* dont_touch = "true" *)  wire                       sfr_wr      ;
 (* dont_touch = "true" *)  wire                       sfr_rd      ;
  
  //external ram interface   or user-defined peripheral reg
(* dont_touch = "true" *)wire [ 7:0]                 ext_data;
(* dont_touch = "true" *) wire [12:0]                mem_addr    ;
(* dont_touch = "true" *)wire [ 7:0]                mem_data_out;
(* dont_touch = "true" *)wire [ 7:0]                mem_data_in ;
(* dont_touch = "true" *)wire                       mem_wr_n    ;
(* dont_touch = "true" *)wire                       mem_rd_n    ;

wire                       fire_out    ;
wire                       fire_start  ;
wire                       fire_out_first    ;
wire                       fire_out_second   ;
wire                       fire_ext_sram;
wire                       fire_cyc;
wire                       fire_uart;
wire                       fire_tx_end;
wire                       fire_cycsecond;
 (* dont_touch = "true" *)wire                       in_A        ;
 (* dont_touch = "true" *)wire                       out_R       ;
//wire                       in_R_note_1 ;
 (* dont_touch = "true" *)wire                       out_R_delay_final1;
 (* dont_touch = "true" *)wire                       out_R_delay_final2;
 (* dont_touch = "true" *)wire                       out_R_delay_final3;
 (* dont_touch = "true" *)wire                       in_A_icache ;
// (* dont_touch = "true" *)wire                       in_A_click3;
 (* dont_touch = "true" *)wire                       out_R_icache;
 (* dont_touch = "true" *)wire                       in_A_icache_click2;
 (* dont_touch = "true" *)wire                       in_A_dcache_read;
 (* dont_touch = "true" *)wire                       out_R_dcache_read;
 (* dont_touch = "true" *)wire                       in_A_dcache_write;
 (* dont_touch = "true" *)wire                       out_R_dcache_write;


 (* dont_touch = "true" *)wire                       out_R_delay5;
 (* dont_touch = "true" *)reg     [5:0]  counter;
 (* dont_touch = "true" *)reg            counter_state_end;
 (* dont_touch = "true" *)reg            counter_state_start;

 (* dont_touch = "true" *)wire         second_begin;
 wire   fire_rx;
 wire   [7:0] rx_data;
 wire   fire_rx_end;
 /**************************ila********************************/

  /************************assignment***************************/
  //interrupt
  assign int0_n = 1'b1;
  assign int1_n = 1'b1;
  
  //serial port 0
  assign rxd0_in = 1'b0;
  
  //timer0/1
  assign t0 = 1'b1;
  assign t1 = 1'b1;
  
  //sfr signal
//  assign sfr_data_in = 8'b0;
  assign sfr_data_in = rx_data;
  //external ram interface
  
//  assign mem_data_in = 8'b0;

IBUFDS sys_clk_ibufgds   
(
.O                      (sys_clk                  ),
.I                      (sys_clk_p                ),
.IB                     (sys_clk_n                )
);

rst_filter rst(
        .clk(sys_clk),
        .rst_n(rst_n),
        .rst_n_out(i_rst_n)
    );

always@(posedge sys_clk or negedge i_rst_n)begin
    if(!i_rst_n)begin
        counter_state_start <= 'b1;
        counter_state_end <= 'b0;
    end else if(counter == 6'b000010)begin    
        counter_state_start <= 'b0;
    end else if(counter == 6'b101010) begin
        counter_state_end <= 'b1;
    end else begin
        counter_state_start <= counter_state_start;
        counter_state_end <= counter_state_end;
    end
end
 
always@(posedge sys_clk or negedge i_rst_n)begin
    if(!i_rst_n)begin
        counter <= 'b0;
    end else if(counter_state_end == 1'b1)begin
        counter <= 'b0;
    end else begin
        counter <= counter + 1;
    end
end  

always@(posedge sys_clk or negedge i_rst_n)begin
    if(!i_rst_n)begin
        in_R <= 'b1;
    end else if((counter_state_start==0)&&(counter_state_end==0))begin
        in_R <= 'b0;
    end else begin
        in_R <= 'b1;
        end
end



(* keep_hierarchy = "yes" *)mcu u_mcu(
            .fire_out_first (fire_out_first) , 
            .fire_out_second(fire_out_second),
            .fire_cyc       (fire_cyc),
            .fire_cycsecond (fire_cycsecond ),
            .por_n        (i_rst_n       ), 
//            .rst_in_n     (rst_n       ), 
//            .rst_out_n    (            ), 
            .test_mode_n  (1'b1        ), 
             
            .stop_mode_n  (            ), 
            .idle_mode_n  (            ),         
             
            //int
            .int0_n       (int0_n      ), 
            .int1_n       (int1_n      ), 
            .int2         (1'b0        ), 
            .int3_n       (1'b1        ), 
            .int4         (1'b0        ), 
            .int5_n       (1'b1        ), 
            
            .pfi          (1'b0        ),  //power failed
            .wdti         (1'b0        ),  //watchdog
            
            //serial port
            .rxd0_in      (rxd0_in     ), 
            .rxd0_out     (rxd0_out    ), 
            .txd0         (txd0        ), 
            
            .rxd1_in      (1'b0        ), 
            .rxd1_out     (            ), 
            .txd1         (            ), 
            
            //timer/counter input/output
            .t0           (t0          ), 
            .t1           (t1          ), 
            .t2           (1'b0        ), 
            .t2ex         (1'b0        ),
	    
            .t0_out       (t0_out      ), 
            .t1_out       (t1_out      ), 
            .t2_out       (            ), 
	    
            // interal ram interface
            .iram_addr    (ram_addr    ), 
            .iram_data_out(ram_data_out),  //mcu data to iram 
            .iram_data_in (ram_data_in ),  //iram data to mcu
            .iram_we_n    (ram_wen     ),
            
            // interal rom interface
            .irom_addr    (rom_addr    ), 
            .irom_data    (rom_data    ), 
            .irom_rd_n    (rom_rd      ),

	    //sfr interface
            .sfr_addr     (sfr_addr    ), 
            .sfr_data_out (sfr_data_out), 
            .sfr_data_in  (sfr_data_in ), 
            .sfr_wr       (sfr_wr      ), 
            .sfr_rd       (sfr_rd      ),
            
            //external ram interface or user-defined peripheral reg
            .mem_addr     (mem_addr    ), 
            .mem_data_out (mem_data_out), 
            .mem_data_in  (mem_data_in ), 
            .mem_wr_n     (mem_wr_n    ), 
            .mem_rd_n     (mem_rd_n    )
	                               );
	                               
(* keep_hierarchy = "yes" *)click_control async_control(
        .rst_n                      (i_rst_n              ),
        .in_R                       (in_R         ),         //start
        .out_R_icache               (out_R_icache       ),         //from  icache
        .in_A_icache_click2         (in_A_icache_click2 ),         //from  icache
        .in_A_dcache_read           (in_A_dcache_read   ),         //from  dcache
        .out_R_dcache_read          (out_R_dcache_read  ),         //from  dcache
        .in_A_dcache_write          (in_A_dcache_write  ),         //from  dcache
        .out_R_dcache_write         (out_R_dcache_write ),         //from  dcache        
        .in_A_icache                (in_A_icache        ),         //to    icacahe
        .out_R_delay_final2         (out_R_delay_final2 ),         //to    icache
        .out_R_delay_final1         (out_R_delay_final1 ),         //to    dcache        
//        .in_A_click3                (in_A_click3        ),         //to    dcache        
        .out_R_delay_final3         (out_R_delay_final3 ),         //to    dcache
        .out_R_delay5               (out_R_delay5       ),         //to    ext_sram
        .fire_start                 (fire_start         ),
        .fire_out_first             (fire_out_first     ),
        .fire_ext_sram              (fire_ext_sram      ),
        .fire_cyc                   (fire_cyc           ),
        .fire_uart                  (fire_uart          ),
        .fire_tx_end                (fire_tx_end        ),
        .fire_out_second            (fire_out_second    ),
        .o_second_begin             (second_begin     ),
        .fire_cycsecond             (fire_cycsecond     ),
        .fire_rx                    (fire_rx            ),
        .fire_rx_end                (fire_rx_end        )           
    );
    

(* keep_hierarchy = "yes" *)icache_control    icache(
        .in_R                   (out_R_delay_final2),   //out_R_delay_final2
        .in_A                   (    in_A_icache   ),   //in_A_icache
        .second_begin           (second_begin       ),
//        .rst_n                  (       rst_n      ),
        .rom_addr               (      rom_addr    ),
        .rom_rd                 (       rom_rd     ),
        .out_R_icache           (   out_R_icache   ),
        .in_A_icache_click2     (in_A_icache_click2),
        .icache_data            (      rom_data    )                   
    );

(* keep_hierarchy = "yes" *)dcache_control  dcache(
//        .rst_n                  (       rst_n      ),
        .in_R_rst               (in_R              ),
        .in_R_delay_final1      (out_R_delay_final1),
        .in_R_delay_final3      (out_R_delay_final3),
//        .out_A_click3           (    in_A_click3   ),
        .ram_data_out           (    ram_data_out  ),
        .ram_addr               (     ram_addr     ),
        .ram_wen                (     ram_wen      ),
        .fire_ext_sram          (     fire_ext_sram),
        .in_A_dcache_read       ( in_A_dcache_read ),
        .out_R_dcache_read      ( out_R_dcache_read),
        .in_A_dcache_write      ( in_A_dcache_write),
        .out_R_dcache_write     (out_R_dcache_write),      
        .ram_data_in            (   ram_data_in    )
    ); 
    
//(* keep_hierarchy = "yes" *)ext_sram_control    ext_sram(
//        .out_R_dcache_read      (   out_R_delay5   ),      //in_R
//        .in_A_dcache_write      ( in_A_dcache_write),      //out_A
////        .rst_n                  (       rst_n      ),
//        .mem_addr               (       mem_addr   ),
//        .mem_data_out           (   mem_data_out   ),        
//        .mem_wr_n               (   mem_wr_n       ),
//        .mem_rd_n               (       mem_rd_n   ),
//        .mem_data_in            (   mem_data_in     )
//    );
     
(* keep_hierarchy = "yes" *)uart_unit uart(  .fire_uart(fire_uart),
                    .fire_rx(fire_rx),
                    .rst_n(i_rst_n),    
                    .in_R_rst(in_R),            
                    .sys_clk(sys_clk),
                    .sfr_addr(sfr_addr), 
                    .sfr_data_out(sfr_data_out), 
                    .rx_data(rx_data), 
                    .sfr_wr(sfr_wr), 
                    .sfr_rd(sfr_rd),
                    .fire_tx_end(fire_tx_end),
                    .uart_tx(uart_tx),
                    .uart_rx(uart_rx),
                    .fire_rx_end(fire_rx_end)
                    );   
endmodule